﻿using System;
using System.Collections.Generic;
using System.Linq;
using InvestmentIntelligence.DbModel.Models;

namespace InvestmentIntelligence.Data.Repository
{
    public interface IUserRepository
    {
        /// <summary>
        ///     AddUser new User
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        int Add(User user);


        /// <summary>
        ///     Get List Of All USers
        /// </summary>
        /// <returns></returns>
        List<T> GetUserList<T>(Func<IQueryable<User>, IEnumerable<T>> f);

        /// <summary>
        ///     Get user by theirs ID
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        User GetUser(int userId);

        /// <summary>
        ///     Get user by theirs loginName
        /// </summary>
        /// <param name="loginName"></param>
        /// <returns></returns>
        User GetUser(string loginName);

        /// <summary>
        ///     Reset password. Get user by theirs email
        /// </summary>
        /// <param name="emailAddress"></param>
        /// <returns></returns>
        User GetUserByEmail(string emailAddress);

        /// <summary>
        ///     Update User
        /// </summary>
        /// <param name="user"></param>
        void UpdateUser(User user);

        /// <summary>
        ///     Update User password
        /// </summary>
        void UpdateUserPassword(int userId, string password);


        /// <summary>
        ///     Get role
        /// </summary>
        /// <returns></returns>
        Role GetRole(int id);

        /// <summary>
        ///     Get role
        /// </summary>
        /// <returns></returns>
        Role GetRoleWithUsers(int id);

        /// <summary>
        ///     Get list of available roles
        /// </summary>
        /// <returns></returns>
        List<T> GetRoles<T>(Func<IQueryable<Role>, IEnumerable<T>> f);

        /// <summary>
        ///     Get list of available roles by entity id
        /// </summary>
        /// <param name="entityId"></param>
        /// <returns></returns>
        List<T> GetRoles<T>(Func<IQueryable<Role>, IEnumerable<T>> f, int entityId);

        /// <summary>
        ///     Remove role with (users not by removed)
        /// </summary>
        /// <param name="id"></param>
        void RemoveRole(int id);

        /// <summary>
        ///     Create new role
        /// </summary>
        /// <param name="role"></param>
        int AddRole(Role role);

        /// <summary>
        ///     Add new role for existing user
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="roleId"></param>
        void AttachRoleToUser(int userId, int roleId);

        /// <summary>
        ///     Remove Role from user
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="roleId"></param>
        void RemoveRoleFromUser(int userId, int roleId);

        /// <summary>
        ///     Get all users which share the same fund/book with given user
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        List<User> GetSharedUsers(int userId);

        /// <summary>
        /// Get distinct fund/books ids of all shared users with given user
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        List<int> GetSharedFundBooksForUser(int userId);
    }
}